package com.uinnova.product.eam.web.dm.mvc;

import cn.hutool.core.io.file.FileNameUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.binary.core.exception.BinaryException;
import com.binary.core.lang.StringUtils;
import com.binary.core.util.BinaryUtils;
import com.binary.framework.web.RemoteResult;
import com.uinnova.product.eam.model.dm.DataModelBatchResp;
import com.uinnova.product.eam.model.dm.DataModelCiInfo;
import com.uinnova.product.eam.model.dm.DataModelCopyInfo;
import com.uinnova.product.eam.model.dm.DataModelRltInfo;
import com.uinnova.product.eam.model.dm.bean.AttrAndCiDto;
import com.uinnova.product.eam.model.dm.bean.EntityParamDto;
import com.uinnova.product.eam.model.dto.DealAttributeDto;
import com.uinnova.product.eam.model.dto.MoveAttributeDto;
import com.uinnova.product.eam.model.enums.DataBaseType;
import com.uinnova.product.eam.service.dm.DataModelQuerySvc;
import com.uinnova.product.eam.service.dm.DataModelSqlSvc;
import com.uinnova.product.eam.service.dm.DataModelSvc;
import com.uinnova.product.vmdb.comm.doc.annotation.ModDesc;
import com.uinnova.product.vmdb.comm.doc.annotation.MvcDesc;
import com.uino.bean.cmdb.base.ESCIInfo;
import com.uino.bean.cmdb.base.LibType;
import com.uino.bean.cmdb.business.BindCiRltRequestDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.List;

/**
 * 数据建模基础处理相关接口
 *
 * @author wcl
 * @date 2022/7/19
 */
@Slf4j
@RestController
@RequestMapping("/dataModel")
@MvcDesc(author = "wcl", desc = "数据建模业务相关接口")
public class DataModelMvc {

    @Resource
    private DataModelSvc dataModelSvc;
    @Resource
    private DataModelQuerySvc querySvc;
    @Resource
    private DataModelSqlSvc dataModelSqlSvc;

    @PostMapping("/saveOrUpdate")
    @ModDesc(desc = "保存、更新实体或实体属性", pDesc = "ci信息", rDesc = "实体或实体属性信息", rType = RemoteResult.class)
    public RemoteResult saveOrUpdate(@RequestBody DealAttributeDto dto) {
        BinaryUtils.checkEmpty(dto.getCiInfo().getCi(), "ci");
        BinaryUtils.checkEmpty(dto.getCiInfo().getCi().getDiagramId(), "diagramId");
        DataModelCiInfo result = dataModelSvc.saveOrUpdate(dto);
        return new RemoteResult(result);
    }

    @PostMapping("/saveOrUpdateAttrBatch")
    @ModDesc(desc = "批量保存或更新实体属性信息(ID存在则更新)", pDesc = "实体属性对象信息", pType = ESCIInfo.class, rDesc = "1成功0失败", rType = Integer.class)
    public RemoteResult saveOrUpdateAttrBatch(@RequestBody List<ESCIInfo> ciList) {
        BinaryUtils.checkEmpty(ciList, "对象信息");
        Integer result = dataModelSvc.saveOrUpdateAttrBatch(ciList);
        return new RemoteResult(result);
    }

    @PostMapping("/batch/save/entity")
    @ModDesc(desc = "批量保存、更新实体", pDesc = "实体ci集合", rDesc = "实体", rType = RemoteResult.class)
    public RemoteResult saveOrUpdateEntityBatch(@RequestBody DealAttributeDto dto) {
        BinaryUtils.checkEmpty(dto.getCiList(), "ci");
        BinaryUtils.checkEmpty(dto.getDiagramId(), "diagramId");
        BinaryUtils.checkEmpty(dto.getOwnerCode(), "ownerCode");
        DataModelCiInfo result = dataModelSvc.saveOrUpdateEntityBatch(dto);
        return new RemoteResult(result);
    }

    @PostMapping("/copyAttribute")
    @ModDesc(desc = "批量复制实体属性", pDesc = "实体code,属性ci信息", rDesc = "实体属性信息", rType = RemoteResult.class)
    public RemoteResult copyAttribute(@RequestBody DealAttributeDto dto) {
        BinaryUtils.checkEmpty(dto.getCiList(), "ci");
        BinaryUtils.checkEmpty(dto.getCiCode(), "实体code");
        DataModelCiInfo result = dataModelSvc.copyAttribute(dto);
        return new RemoteResult(result);
    }

    @PostMapping("/copyEntity")
    @ModDesc(desc = "复制实体", pDesc = "实体ciCode集合", rDesc = "实体及实体属性信息", rType = RemoteResult.class)
    public RemoteResult copyEntity(@RequestBody DealAttributeDto dto) {
        BinaryUtils.checkEmpty(dto.getCiCodeList(), "ciCode");
        BinaryUtils.checkEmpty(dto.getDiagramId(), "视图id");
        BinaryUtils.checkEmpty(dto.getSheetId(), "分页id");
        List<DataModelCopyInfo> result = dataModelSvc.copyEntity(dto);
        return new RemoteResult(result);
    }

    @PostMapping("/dealAttributeBatch")
    @ModDesc(desc = "数据建模实体批量保存、删除属性", pDesc = "批量处理信息", rDesc = "实体属性列表信息", rType = RemoteResult.class)
    public RemoteResult dealAttributeBatch(@RequestBody DealAttributeDto dto) {
        BinaryUtils.checkEmpty(dto.getCiCode(), "实体ciCode");
        BinaryUtils.checkEmpty(dto.getDiagramId(), "视图id");
        BinaryUtils.checkEmpty(dto.getSheetId(), "分页id");
        DataModelBatchResp result = dataModelSvc.dealAttributeBatch(dto);
        return new RemoteResult(result);
    }

    @PostMapping("/selectEntityAndAttr")
    @ModDesc(desc = "数据建模查询实体和属性列表", pDesc = "paramDto", rDesc = "实体属性列表信息", rType = RemoteResult.class)
    public RemoteResult selectEntityAndAttr(@RequestBody @Validated EntityParamDto paramDto) {
        BinaryUtils.checkEmpty(paramDto.getClassName(), "分类名称不能为空");
        return new RemoteResult(querySvc.selectEntityAttrList(paramDto));
    }

    @GetMapping("/selectRangeList")
    @ModDesc(desc = "查询值域列表接口", pDesc = "paramDto", rDesc = "无", rType = RemoteResult.class)
    public RemoteResult selectRangeList(@RequestParam LibType libType) {
        String ident = "domainClass";
        return new RemoteResult(querySvc.selectDataStandardList(ident,libType));
    }



    @GetMapping("/selectDataStandardList")
    @ModDesc(desc = "查询数据标准列表", pDesc = "模糊查询字段", rDesc = "数据标准信息", rType = RemoteResult.class)
    public RemoteResult selectDataStandardList(@RequestParam(required = false) String word, @RequestParam LibType libType) {
        String ident = "standard";
        return new RemoteResult(querySvc.selectDataStandardList(ident,libType));
    }

    @PostMapping("/bindCiRlt")
    @ModDesc(desc = "保存关系数据", pDesc = "关系数据传输对象", pType = BindCiRltRequestDto.class, rDesc = "画布更新内容", rType = DataModelRltInfo.class)
    public RemoteResult bindCiRlt(@RequestParam(defaultValue = "PRIVATE") LibType libType,
                                  @RequestParam(defaultValue = "false") Boolean fastShape,
                                  @RequestBody BindCiRltRequestDto reqBean) {
        BinaryUtils.checkEmpty(reqBean.getSourceCiCode(), "源端ciCode");
        BinaryUtils.checkEmpty(reqBean.getTargetCiCode(), "目标端ciCode");
        BinaryUtils.checkEmpty(reqBean.getDiagramId(), "视图Id");
        BinaryUtils.checkEmpty(reqBean.getSheetId(), "分页Id");
        DataModelRltInfo result = dataModelSvc.bindCiRlt(reqBean, fastShape, libType);
        return new RemoteResult(result);
    }

    @PostMapping("/delRltByCode")
    @ModDesc(desc = "删除单条关系线", pDesc = "关系code及视图信息", pType = DealAttributeDto.class, rDesc = "画布更新内容", rType = DataModelRltInfo.class)
    public RemoteResult delRltByCode(@RequestBody DealAttributeDto dto) {
        BinaryUtils.checkEmpty(dto.getCiCode(), "关系Code");
        BinaryUtils.checkEmpty(dto.getDiagramId(), "视图id");
        BinaryUtils.checkEmpty(dto.getSheetId(), "分页id");
        DataModelRltInfo result = dataModelSvc.delRltByCode(dto);
        return new RemoteResult(result);
    }

    @PostMapping("/delEntityOrAttribute")
    @ModDesc(desc = "删除单条实体属性", pDesc = "实体及实体属性code", pType = DealAttributeDto.class, rDesc = "画布更新内容", rType = DataModelRltInfo.class)
    public RemoteResult delEntityOrAttribute(@RequestBody DealAttributeDto dto) {
        BinaryUtils.checkEmpty(dto.getDiagramId(), "视图id");
        BinaryUtils.checkEmpty(dto.getSheetId(), "分页id");
        DataModelRltInfo result = dataModelSvc.delEntityOrAttribute(dto);
        return new RemoteResult(result);
    }

    @PostMapping("/moveAttribute")
    @ModDesc(desc = "移动单条实体属性到另一个实体,或同实体内移动", pDesc = "源端、目标端实体及实体属性code", pType = MoveAttributeDto.class, rDesc = "画布更新内容", rType = DataModelRltInfo.class)
    public RemoteResult moveAttribute(@RequestBody @Validated MoveAttributeDto dto) {
        DataModelRltInfo result = dataModelSvc.moveAttribute(dto);
        return new RemoteResult(result);
    }

    @PostMapping("/quickDrawingEr")
    @ModDesc(desc = "er图自动成图", pDesc = "源端、目标端实体及实体属性code", pType = MoveAttributeDto.class, rDesc = "", rType = DataModelRltInfo.class)
    public RemoteResult quickDrawingEr(@RequestBody String body) {
        JSONObject json = JSON.parseObject(body);
        String diagramId = json.getString("diagramId");
        LibType libType = json.getObject("libType", LibType.class);
        AttrAndCiDto result =dataModelSvc.quickDrawingEr(diagramId, libType);
        return new RemoteResult(result);
    }

    @PostMapping("/ddl/export")
    @ModDesc(desc = "导出ddl", pDesc = "视图加密id", rDesc = "视图信息", rType = RemoteResult.class)
    public ResponseEntity<byte[]> exportDDL(@RequestBody JSONObject body) {
        String diagramId = body.getString("diagramId");
        LibType libType = body.getObject("libType", LibType.class);
        DataBaseType dataBase = body.getObject("dataBase", DataBaseType.class);
        BinaryUtils.checkEmpty(diagramId, "视图id");
        BinaryUtils.checkEmpty(libType, "libType");
        return dataModelSqlSvc.exportCreateTable(diagramId, libType, dataBase);
    }

    @PostMapping("/ddl/import")
    @ModDesc(desc = "导入ddl", pDesc = "ddl文件", rDesc = "实体及实体属性", rType = RemoteResult.class)
    public RemoteResult importDDL(@RequestParam(name = "file") MultipartFile file,
                                  @RequestParam String diagramId,
                                  @RequestParam(defaultValue = "MYSQL") DataBaseType dataBase) {
        BinaryUtils.checkEmpty(diagramId, "视图id");
        //判断是否为.sql格式文件
        String suffix = FileNameUtil.getSuffix(file.getOriginalFilename());
        if (StringUtils.isEmpty(suffix) || !"sql".equals(suffix)) {
            throw new BinaryException("导入失败,仅支持sql格式的文件");
        }
        AttrAndCiDto result = dataModelSqlSvc.importDDL(file, diagramId, dataBase);
        return new RemoteResult(result);
    }

}
